﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace EntityFramework.Helper.Persister
{
    /// <summary>
    /// Class representing the base class to one EntityObject.
    /// </summary>
    /// <typeparam name="E">The type of the EntityObject.</typeparam>
    public abstract class Persister<E> : IPersister<E> where E : System.Data.Objects.DataClasses.EntityObject
    {
        #region Construtors

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="context">The persister's context.</param>
        protected Persister(System.Data.Objects.ObjectContext context) 
        {
            // defines the persister context.
            Context = context;

            // instancieates the persister's entity object collection.
            EntityObjects = new HashSet<E>();
        }

        #endregion

        #region Methods

        /// <summary>
        /// Adds the entity object to the persister context.
        /// </summary>
        /// <param name="entityObject">The entity object to be added.</param>
        /// <returns>True if it was correctly added, false if not.</returns>
        public bool AddToPersister(E entityObject)
        {
            EntityObjects.Add(entityObject);
            
            return true;
        }

        /// <summary>
        /// Returns an EntityObject.
        /// </summary>
        /// <returns>EntityObject</returns>
        public E GetEntityObject()
        {
            // gets the entity object type.
            Type t = typeof(E);

            // gets the entity object constructor.
            ConstructorInfo constructor = t.GetConstructor(new Type[0]);

            // creates and populates the instance od the entity object.
            return (E)constructor.Invoke(new object[0]);
        }

        /// <summary>
        /// Saves the EntityObject.
        /// </summary>
        public virtual void SavePersisterContext()
        {
            foreach (E obj in EntityObjects)
            {
                Context.AddObject(typeof(E).Name, obj);
            }

            Context.SaveChanges();
        }

        /// <summary>
        /// Deletes the EntityObject from the informed context.
        /// </summary>
        public virtual void DeletePersisterContext()
        {
            foreach (E obj in EntityObjects)
            {
                Context.DeleteObject(obj);
            }

            Context.SaveChanges();
        }

        /// <summary>
        /// Saves a specific entity object.
        /// </summary>
        /// <param name="entityObject">The entity object to be saved.</param>
        public virtual void Save(E entityObject)
        {
            Context.AddObject(typeof(E).Name, entityObject);
            Context.SaveChanges();
        }

        /// <summary>
        /// Deletes a specific entity object.
        /// </summary>
        /// <param name="entityObject">The entity object to be deleted.</param>
        public virtual void Delete(E entityObject)
        {
            Context.DeleteObject(entityObject);
            Context.SaveChanges();
        }

        #endregion

        #region IPersister Members

        /// <summary>
        /// Defines the context of the Persister.
        /// </summary>
        public System.Data.Objects.ObjectContext Context
        {
            get;
            set;
        }

        /// <summary>
        /// Set of persister's entity objects. 
        /// </summary>
        public HashSet<E> EntityObjects
        {
            get;
            internal set;
        }

        #endregion
    }
}
